home *** CD-ROM | disk | FTP | other *** search
Text File | 1992-09-27 | 126.4 KB | 4,190 lines |
-
-
- FST (Fitted) Modula-2 Version 3.0
-
- (C) Copyright 1987,1988,1992 Fitted Software Tools.
- All rights reserved.
-
-
- Fitted Software Tools
- P.O.Box 867403
- Plano, TX 75086
- BBS 214/517-4629
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- DISCLAIMER OF WARRANTY
-
- THIS SOFTWARE AND MANUAL ARE PROVIDED "AS IS" AND WITHOUT WARRANTIES
- AS TO PERFORMANCE OR MERCHANTABILITY.
-
- THIS SOFTWARE IS PROVIDED WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES
- WHATSOEVER. BECAUSE OF THE DIVERSITY OF CONDITIONS AND HARDWARE UNDER
- WHICH THIS SOFTWARE MAY BE USED, NO WARRANTY OF FITNESS FOR A
- PARTICULAR PURPOSE IS OFFERED. THE USER IS ADVISED TO TEST THIS
- SOFTWARE THOROUGHLY BEFORE RELYING ON IT. THE USER MUST ASSUME THE
- ENTIRE RISK OF USING THIS SOFTWARE.
-
-
-
- All the information in this document is believed to be correct at the
- time of publication. We do, however, reserve the right to make any
- changes in product specifications and/or availability without notice.
-
-
-
-
-
-
-
- IBM is a registered trademark of International Business Machines
- Corporation.
-
- 1
-
-
-
-
-
-
-
-
-
-
- To my parents
-
-
-
-
-
- I implemented FST Modula-2 for my mother; I could not have done it
- without my father's support and encouragement.
-
- Everything that is good in me, I owe them.
-
-
-
- Roger Carvalho
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Introduction 3
-
-
-
-
-
-
-
-
- Chapter 1
-
- Introduction
-
-
-
- Thank you for your interest in our Modula-2 compiler.
-
- This system features a Modula-2 compiler with an integrated editor and
- "make" facility, a program linker, a makefile generator, and an
- execution profiler.
-
- The compiler generates code for the Intel 8086 "huge" or "large"
- memory model: In the "huge" memory model, each module has its own data
- and code segment, each of which can be up to 64k in size; In the
- "large" memory model, all the modules' static data is combined into a
- single data segment. In either model, pointers are 4 bytes long and
- all the leftover memory is available for the "heap". More restrictive
- memory models are not supported.
-
- All the library and runtime support source code is available to our
- registered users (see Shareware).
-
- We hope that our effort will prove itself worthy of your support.
-
-
-
-
-
-
- 1.1 A few words from the author
-
-
- I dedicated many years' worth of my spare time to the development of
- this product.
-
- FST Modula-2 v1.0 was my third attempt at a complete Modula-2
- compiler. From the first two, I reused the knowledge acquired.
-
- Why Modula-2? Remember the Pascal vs C debate? Well, I liked (and
- used) both. I saw Modula-2 as providing the best of both, plus some
- more.
-
- A safe language that let you do all the low level stuff? Utopia? No,
- this was for real!
-
- Ten years after I first met Modula-2, I still do most of my
-
-
-
- Introduction 4
-
-
- programming in C...
-
- I am often asked if I will implement the forthcoming ISO standard. I
- will not track the development of the standard; When the standard is
- published (my understanding is that this will not happen for at least
- another year), I will decide what to do.
-
- Here is what I am planning for the future -- please keep in mind that
- I am not promising anything and that my drive to do this will be
- somewhat proportional to the interest generated by this release of the
- compiler.
-
- Many users have asked for a debugger. Since I do not much care for
- debuggers, I have been resisting. Well, no more. I started work on a
- debugger. I still don't know when the debugger will be ready; I can,
- however, tell you what it is: A simple debugger with only the basics
- (step, run to breakpoint, examine variables, ... ); But you will get
- the full source code and can hack it to your heart's content. How
- does that sound?!
-
- At the same time that I introduce the debugger, I will discontinue
- support for OBJ files. In retrospect, adding OBJ file support was a
- bad decision. If I add support for Windows, M2Link will be changed to
- handle DLLs.
-
- I will continue to work on the object oriented extensions too, if the
- ones that I am introducing are well accepted.
-
- So, if you care about any of this, one way or another, please let me
- know!
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Introduction 5
-
-
-
-
-
-
- 1.2 Hardware requirements
-
-
- This system will run on IBM PC, PC/AT, or compatible systems with at
- least 512K of RAM, two double sided floppy disk drives and a
- monochrome display adapter, color graphics adapter or equivalent.
-
- A hard disk and 640K of RAM are, however, recommended.
-
-
-
-
-
-
- 1.3 Software requirements
-
-
- This system requires DOS version 2.0 or later.
-
- No other software is required to use this system, but you will need an
- assembler if you intend to modify one of the following runtime support
- modules: M2Reals (floating point support), M2Longs (LONG arithmetic)
- or M2Procs (coroutine handling).
-
-
-
-
-
-
- 1.4 For users upgrading to release 3
-
-
- We are happy to announce that, finally, the system is smart enough to
- report runtime errors by module name and line number!
-
- Release 3.0 also adds support for object oriented programming. Please
- refer to the chapter on Classes for more information.
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Software installation 6
-
-
-
-
-
-
-
-
- Chapter 2
-
- Software installation
-
-
-
- Before starting, please print the file READ.ME, which provides
- information about the distibution contents.
-
-
-
-
-
-
- 2.1 Theory
-
-
- The library module TermIO (through which Terminal does its I/O)
- requires that the ANSI.SYS driver be installed.
-
- The executable files (MC.EXE, M2LINK.EXE, ...) should, for ease of
- operation, be placed in a drive/directory named in the DOS PATH
- variable.
-
- The editor configuration file M2ED.CFG must be accessible through the
- DOS PATH.
-
- Both the compiler and the linker will use the environment variable
- M2LIB to locate required library modules (the format for the M2LIB
- entry matches that of the DOS PATH).
-
- The environment variable M2MODEL may be set to 'HUGE' or 'LARGE'. IF
- M2MODEL is not set, the compiler, by default, assumes that you want to
- compile for the HUGE model.
-
- The compiler and utilities in this package do not keep many files open
- simultaneously. If you set the FILES parameter in CONFIG.SYS to 10
- you should not encounter any problems. For performance
- considerations, you should also allocate more than the default number
- of buffers for DOS: If you are running on a PC class machine, try
- allocating 20 buffers in your CONFIG.SYS. On an AT class machine, try
- 60 to 99 buffers.
-
- Example CONFIG.SYS:
-
- DEVICE=ANSI.SYS
- FILES=10
-
-
-
- Software installation 7
-
-
- BUFFERS=20
-
- This compiler is a memory hog -- you heard it here first! This is
- neither good nor bad, simply an implementation decision. Source
- modules being compiled, for example, are sucked into memory with a
- single read system call.
-
- Source files (either being compiled or edited) are loaded at the top
- of available memory. This, of course clobbers the resident portion of
- COMMAND.COM. Because this software was developed on a relatively slow
- system, with a very slow hard disk, we decided that it would be a good
- idea to, on request, preserve the resident portion of COMMAND.COM.
- Unless you are running a floppy based system, do not worry about
- this.
-
- To enable the "COMMAND save" feature of the compiler, which will stop
- it from clobbering the resident portion of COMMAND.COM, just add the
- following line to your AUTOEXEC.BAT file:
-
- SET CMDSIZE=NN
-
- where NN is the size of the resident portion of COMMAND.COM in K (18
- for DOS 3.0).
-
- MC clobbers the top of the memory space available for use during
- initialization. Therefore, to find out the size of the resident
- portion of COMMAND.COM, try the following procedure: start by setting
- CMDSIZE to the size of COMMAND.COM. If now you execute MC, exit it,
- and press the F3 key, DOS will still remember your MC command.
- Decrement CMDSIZE and retry the MC test until the system forgets your
- last command (COMMAND.COM had to be reloaded).
-
- The compiler supports 2 different memory models. If you are going to
- be using both memory models, keep each set of library object files in
- a different directory, and change the M2LIB path according to the
- model in use. We use the following BAT files to take care of this:
-
-
- LARGE.BAT:
- set M2MODEL=LARGE
- set M2LIB=C:\M2\LIB;C:\M2\LIB\L
-
- HUGE.BAT:
- set M2MODEL=HUGE
- set M2LIB=C:\M2\LIB;C:\M2\LIB\H
-
- where \M2\LIB is the directory where all the DEF and BIN files reside,
- \M2\LIB\L contains the LARGE memory model M2O files,...
-
- In the following discussion we will, for simplicity sake, assume that
- you will be using only one of the memory models.
-
-
-
-
-
- Software installation 8
-
-
-
-
-
-
- 2.2 Recommended setup for a system with 2 floppy drives
-
-
- This whole system is too large to fit in a single 360k floppy.
- Therefore, it is recommended that you build a "compiler" floppy and a
- "utilities" floppy (you may combine them both in a 720k or larger
- floppy).
-
- On the compiler floppy, place the compiler (MC.EXE), the file M2ED.CFG
- and DOS' COMMAND.COM.
-
- The utilities floppy will take the rest of the basic system: the
- linker (M2LINK.EXE), and the library and runtime support object files
- (*.M2O and *.BIN) and other .EXE files that you may want and happen to
- fit.
-
- On your work disk you must create the directory \LIB and copy all the
- library definitions modules (*.DEF) to it.
-
- Assuming that you will use drive A for the compiler and utilities disk
- and drive B as your work drive, add the following to your AUTOEXEC.BAT
- file:
-
- SET PATH=A:
- SET M2LIB=B:\LIB;A:
-
- If you follow these suggestions, you may use most of the system's
- capabilities. Just remember to swap the floppy in drive A before and
- after invoking the linker from the compiler's menu.
-
-
-
-
- 2.3 Recommended setup for a hard disk system
-
-
- Place the executable files (*.EXE) and M2ED.CFG in a directory
- currently in the DOS search path, or in a new directory (ex: \M2) to
- be added to the PATH list. Example:
-
- SET PATH=C:\BIN;C:\M2
-
- Make a directory for the library files (ex: \M2\LIB) and copy all the
- .DEF, .M2O and .BIN files to it. To the AUTOEXEC.BAT file add the
- line:
-
- SET M2LIB=C:\M2\LIB
-
- You will probably want to create a directory for your own reusable
-
-
-
- Software installation 9
-
-
- library modules. This directory can be added to the M2LIB environment
- variable. Example:
-
- SET M2LIB=C:\M2\LIB;C:\MYLIB
-
- You may keep your projects in their own, individual, directories.
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- A little tour through the system 10
-
-
-
-
-
-
-
-
- Chapter 3
-
- A little tour through the system
-
-
-
- After you finish the installation as described above, please copy the
- files identified as the "system tour files" in the READ.ME file to
- your work disk or directory.
-
- Because we do not know your particular system configuration, in the
- following examples we will assume the worst possible scenario.
- Therefore, some of the capabilities of this system will not be fully
- exploited. Specifically, we will not invoke the linker or run the
- programs from the compiler menu.
-
-
-
-
-
-
- 3.1 The tour
-
-
- First, we will look at the unnatural case of compiling, linking and
- running a program that works the first time around. Please execute
- the following commands:
-
- MC SIEVE /C
- M2LINK SIEVE /O
-
- Well, that's it! Ready to run...
-
- SIEVE
-
- Now for the more usual case:
-
- MC BADSIEVE
-
- From the compiler menu, select 'C' for compile.
-
- Gee, that was quick! Press RETURN to take a look at our errors...
-
- The cursor is now positioned at the location of the first error.
- Using the keys Ctrl-E (find next error) and Ctrl-P (find previous
- error) you may visit all the errors flagged by the compiler. All the
- while, the editor shows the error description on the top line of the
-
-
-
- A little tour through the system 11
-
-
- screen. But, going back to the first error...
-
- We really confused the compiler when we mistakenly typed in '.'
- instead of '..' in the range declaration. Move the cursor back (left
- arrow key) to where the '.' is, type in another '.', and that should
- fix that! As you will see as you type Ctrl-E, that single error
- caused the compiler to dislike a few other things on that same line;
- we will just ignore those errors and go on.
-
- Go on to the next error location (line 22). This time, we should have
- used a ']' but typed '}' instead. The backspace key will delete the
- offending character; now, type the ']' in its place.
-
- And that is that. Shall we try to compile the program again?
-
- Press Alt-S to save the file, Alt-Q to leave the editor and, back at
- the main menu, select 'C'.
-
- More errors?!
-
- These errors should have been detected during pass2 of the
- compiler; If not, you may try to fix these errors and recompile,
- or you may opt for loading and compiling the new file
- BADSIEV1.MOD, which contains the earlier fixes.
-
- Going back to the editor...
-
- We find that we used the identifier 'cnt' which is undefined; we
- really meant to use count. So, moving the cursor around with the
- cursor keys and/or deleting characters with the backspace or delete
- key, please replace 'cnt' by 'count'.
-
- Searching for the next error...
-
- The next error occurred during the processing of the call to
- WriteCard. What happened here is that WriteCard requires 2 parameters,
- the second one being the size of the field to display. So, to fix it,
- let's insert a comma after 'count' and some number (for example
- 'count,4').
-
- Any more errors? No, that is it...
-
- We now save the file (Alt-S), quit the editor (Alt-Q) and recompile
- (c).
-
- Now, the program should have compiled without errors. If not, you may
- recompile BADSIEV2.MOD instead.
-
- We may now quit the compiler (q).
-
- By now, we have some program that has compiled clean (BADSIEVE,
- BADSIEV1 or BADSIEV2). In what follows, we will assume all went well
- and we have BADSIEVE.
-
-
-
- A little tour through the system 12
-
-
-
- If you look at the directory, you will see the new object module
- created as a result of the previous exercise (BADSIEVE.M2O). The
- compiler always writes its output to a file with the extension 'M2O'.
-
- Let us link and test the program:
-
- M2LINK BADSIEVE /L
-
- We use the /L option so that the line number information written out
- by the compiler to the object file will be preserved by the linker.
- We will need this information later.
-
- BADSIEVE
-
- Hmmm... A runtime error at line 22.
-
- Let's see what happened...
-
- MC BADSIEVE
-
- Pick 'E' to go into the editor and, either move the cursor down to the
- line indicated, or let the editor find it with Alt-G.
-
- So, what is the problem? Well, we declared the 'flag' array to have a
- maximum index of 8190, but 'j' got bigger than that (the FOR loop will
- increment 'j' up to the value of 10000).
-
- You may fix the problem by deleting the '10000' and typing in its
- place 'SIZE'.
-
- Recompile the program, link it, and run it. Did it work? Good.
-
- It is time for you to experiment on your own. But, before you do much
- more, you may want to check out the Editor chapter of the
- documentation.
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- The Compiler 13
-
-
-
-
-
-
-
-
- Chapter 4
-
- The Compiler
-
-
-
- In the Modula-2 language, as defined by Niklaus Wirth, identifiers may
- be used before they are declared, except when they are used in another
- declaration (this restriction does not apply to pointers). This
- forces the compilation process to be done in at least two passes.
-
- To avoid imposing unnecessary restrictions and, yet, provide
- reasonable performance, the two pass approach was selected: During the
- first pass, syntax analysis and declaration analysis are performed;
- The second pass performs the semantic analysis and code generation.
-
- The compiler has an integrated text editor. Should errors be
- encountered, the editor is invoked at the end of the current compiler
- pass (sooner, if an error is found during the processing of an import
- list or if 20 errors are identified).
-
- The compiler also has a built in "make" processor. A makefile must be
- created before this process is invoked. Although you can create a
- makefile using the editor, we recommend that you use the utility
- provided for that purpose: GENMAKE (this utility may be invoked from
- the compiler menu -- G).
-
- The compiler can generate 2 different kinds of object files as
- output. By default, M2O (stands for "Modula-2 Object") files are
- generated. This file format is unique to this compiler, and it is
- optimized for our requirements and those of Modula-2. But the user
- can, through the use of an environment variable (M2OUTPUT), specify
- that standard OBJ files are to be generated instead.
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- The Compiler 14
-
-
-
-
-
-
- 4.1 Running the integrated compiler: MC
-
-
- Compiler invocation:
-
- MC [workModule] [/p mainModule] [/s maxIds idSpace] [/c] [/e]
- [/m] [/d-]
-
- The '/p' option may be used to indicate the name of the main module of
- the program that you are working on (the name should not have an
- extension). If this option is not used, but workModule is entered
- without an extension, the same name is also used for mainModule.
-
- The '/s' option allows you to change the default sizes of the compiler
- identifier tables. The two arguments specify the maximum number of
- different identifiers to be processed, and the total string space to
- be allocated to store these identifiers. The default values are 2000
- and 12000, respectively.
-
- If you use of the '/c' command line option, the compiler starts
- compiling "workModule" immediately and, if no errors are encountered,
- will bring you right back to the DOS prompt. This is useful when
- running the compiler from a batch file:
-
- MC myprog /c
-
- The '/e' option will send you straight into the editor.
-
- The '/m' option invokes the make processor, which will look for the
- file mainModule.MAK for the dependencies list.
-
- The '/d-' option sets the default value of the compiler directives $R
- and $T to '-', disabling the default generation of most runtime error
- checking. We do not recommend disabling the stack overflow checking,
- and the use of '/d-' will not do it.
-
- The compiler always sets the DOS errorlevel to 0 if the last compile
- was successful (no errors); otherwise, the DOS errorlevel is set to 1.
-
- If the compiler is invoked without the '/c', '/e' or '/m' options, you
- will get a screen that looks something like this:
-
-
-
-
-
-
-
-
-
-
-
- The Compiler 15
-
-
-
-
-
- Modula-2 compiler, Version 3.0
- (C) Copyright 1987-1992 Fitted Software Tools. All rights reserved.
-
- Memory model in use: LARGE
- Output file format: M2O
-
- Heap in use: 0K
- Available Heap: 294K
-
- Program:
-
- Work module: work.mod
-
- Program New DOS Quit
- Compile Edit Genmake Make Link eXecute >
-
-
-
- The options at this point are:
-
- Program Specify the name of the main program module.
-
- New Specify another "Work module".
-
- DOS Invoke a new DOS shell. At the DOS prompt, you
- should type EXIT to return to this system.
-
- Quit Return to DOS.
-
- Compile Compile the "Work module".
-
- Edit Edit the "Work module".
-
- Genmake Invoke the GenMake program, passing as argument the
- name in Program -- and '/OBJ', if appropriate.
-
- Make Recompile all the necessary modules as per the rules
- of a makefile (The makefile is assumed to have the
- name in Program and the extension of .MAK). Note: If
- errors are encountered during the compilation of one
- of the modules, the make process is aborted. After
- fixing the errors, select Make again.
-
- Link Invokes the linker (M2Link) passing along as
- arguments the name in Program and '/L'.
-
- eXecute You are prompted for any arguments that you may want
- to pass to the program; The Program is then
- executed.
-
-
-
-
- The Compiler 16
-
-
-
-
-
-
-
- 4.2 Running the freestanding compiler: M2COMP
-
-
- Compiler invocation:
-
- M2COMP filename [/m] [/s maxIds idSpace] [/d-]
-
- filename is the name of the module to compile or, if the /M option is
- used, the name of the makefile to process.
-
- The DOS errorexit is set to 0 if the compilation (make) is successful
- and to 1 otherwise.
-
-
-
-
-
-
- 4.3 The compilation process
-
-
-
-
-
- 4.3.0.1 The input file
-
- If the module to be compiled is already loaded into one of the editor
- buffers, that source is compiled. Otherwise, the compiler tries to
- open the named file.
-
-
-
-
- 4.3.0.2 The imported modules
-
- The compiler and the linker cooperate in assuring that all the modules
- that refer to a particular definition module will have been compiled
- against the same version of that definition module.
-
- To this end, the compiler places in the 'module header' and 'module
- import' records of the object file a "module key". This module key is
- the date of the DEF file used during the compilation of the
- implementation module or during the processing of the IMPORT
- statement.
-
- Due to this, the compiler will not look in the editor buffers for the
- DEF files needed to process an IMPORT list. These are always read in
- from the disk.
-
-
-
- The Compiler 17
-
-
-
-
-
-
- 4.3.0.3 The output file
-
- The output from the compilation of a main module or an implementation
- module is a single output file, with the same name of the source file
- but with the extension of 'M2O' (Modula-2 Object) -- OBJ files are
- created instead, if the environment variable M2OUTPUT so specifies.
-
- The compilation of a definition module does not generate any new
- output files. If the compilation is successful (no errors), the
- compiler simply 'touches' the source file, updating its modification
- time.
-
-
-
-
- 4.3.0.4 A warning
-
- Because of the fact that the compiler uses the date of the DEF file as
- that module's key, you may not modify a DEF file unless you intend to
- recompile all the modules that use it, nor can you copy the file in
- such a way that its date is not preserved.
-
- In particular, if you are going to be transferring your modules
- between computers, you must use some procedure that will preserve all
- the DEF files' dates.
-
- This is probably a good place to point out that, when you use OBJ
- files, you are not protected by this module version checking.
-
-
-
-
-
-
- 4.4 Compiler directives
-
-
- Certain compiler code generation options may be set through directives
- included in the program text. These directives must appear
- immediately at the beginning of a comment; multiple directives may be
- entered in a single comment by separating them by commas. Example
-
- (* $S-, $R+ *)
-
- A '+' sets the directive to TRUE, a '-' sets it to FALSE, and a '='
- pops the directive's value prior to the last '+' or '-'.
-
- The following compiler directives are defined:
-
-
-
-
- The Compiler 18
-
-
- $A Alignment. Default $A+. If enabled, all new variables
- declared are aligned on a word boundary. Record
- fields are packed (not aligned) regardless of the
- setting of this option.
-
- $S Stack overflow checking. Default $S+. If enabled,
- stack overflow checking is performed on entry to a
- procedure and when copying open arrays to a
- procedure's local stack frame.
-
- $R Range checking. Default $R+. If enabled, before any
- assignment is made to a variable of a subrange type,
- the value to be assigned is tested against the limits
- of the subrange type.
-
- $T Array subscript and NIL pointer checking. Default
- $T+. If enabled, any time a subscript operation is
- performed on an array, the subscript value is checked
- to confirm that the operation would not generate an
- address outside the bounds of the array. In
- addition, before a pointer is dereferenced, its value
- is checked for NIL.
-
- $L Generate line number information. Default $L-. If
- this option is enabled, the compiler will include a
- list of source code line numbers and their
- corresponding object code offsets in the output
- file. This line number information is passed on to
- the .DBG file when the program is linked with the /L
- option.
-
-
-
-
- 4.4.0.1 Benchmarks
-
- If you are going to benchmark the code generated by this compiler,
- please disable the generation of runtime error checking on all the
- compilers involved in the comparison.
-
- We feel compelled to spell this out because some other vendors'
- products do not generate runtime error checking by default.
-
-
-
-
-
-
- 4.5 Runtime errors
-
-
- When, during the execution of a program, a runtime error is detected,
- the runtime error handler will terminate the program and write out a
-
-
-
- The Compiler 19
-
-
- message indicating the type of error encountered and its location
- (module name, line number and PC address).
-
-
-
-
- 4.5.1 Trapping runtime errors in your program
-
- The Library module System provides you with a means of intercepting
- runtime errors. The following are the currently defined runtime error
- numbers that may be passed to your error handler routine:
-
- 0 stack overflow ($S option)
- 1 range error ($R or $T option)
- 2 integer/cardinal overflow (divide by zero)
- 3 floating point error
- 4 function did not execute a RETURN
- 5 HALT was invoked
-
-
-
-
- 4.6 Compiler size limits
-
-
- The following are the code and data size limits imposed by this
- compiler:
-
- - A string constant cannot exceed 80 characters. This is also the
- limit set for the size of any identifier.
-
- - When using the HUGE memory model, each compilation module is
- assigned its own data segment, which can be up to 64k in size.
- In the data segment, the compiler allocates the space for all the
- module's global variables and some of the module's constants.
-
- - When using the LARGE memory model, all the modules' data are
- combined, at link time, into a single data segment (64k
- maximum).
-
- - The maximum size of a data structure is 65532 bytes.
-
- - The maximum amount of space allocated for variables local to a
- procedure is 32000 bytes.
-
- - The compiler will also refuse to generate the code to pass, in a
- procedure call, by value, a parameter greater than 65000 bytes in
- size.
-
- The following are the compiler's internal limits:
-
- - The maximum number of different (namewise) identifiers that can
- be processed in a single compilation is 2000. May be overwritten
-
-
-
- The Compiler 20
-
-
- at compiler invocation.
-
- - The total number of characters in all the different (namewise)
- identifiers processed cannot exceed 12000 characters. May be
- overwritten at compiler invocation.
-
- - No single procedure can be translated into more than 10k of
- object code.
-
- - An array of 8k bytes is used to keep track of all the initialized
- data for a module. This imposes a limit on the total amount of
- string, real and long constants used in the compilation module.
-
-
-
-
- 4.7 The language supported
-
-
- This release of the compiler will translate a program written in the
- Modula-2 language as defined by Niklaus Wirth in the 3rd edition of
- his book "Programming in Modula-2", with the exceptions noted bellow:
-
-
-
- - Integer and Cardinal arithmetic overflow is not detected.
-
- - ASM, CLASS, INHERITED, INIT and DESTROY are reserved word in this
- implementation.
-
- - For those programmers that "grew up" in the Hex world, a way to
- define CHAR literals in Hex is provided: 20X corresponds to the
- "space" character in ASCII.
-
-
-
-
- 4.7.1 LONGINT and LONGCARD
-
- This compiler implements the standard types LONGINT and LONGCARD.
-
- Operands of the type LONGINT or LONGCARD may appear in any expression,
- just like INTEGER or CARDINAL. But that is about it!
-
- Subranges of these types are not supported.
-
- No standard procedure, except INC, DEC and the ones listed later in
- this document will accept operands of one of these types.
-
- A variable of type LONGINT or LONGCARD cannot be used as the control
- variable in a FOR loop. Neither can CASE labels be of a LONG type.
-
- Constants of type LONGINT or LONGCARD can be coded in decimal only and
-
-
-
- The Compiler 21
-
-
- must be terminated by an 'L' if the value is less than 65536. Example
-
- 123L and 123567 are valid LONGCARD or LONGINT constant
-
- -1L and -348762 are valid LONGINT constants
-
-
- 4.7.2 LONGREAL
-
- The standard type LONGREAL is implemented.
-
- The rules for the use of LONGREALs are the same as for REALs.
-
- The types REAL and LONGREAL are not compatible, and no automatic
- conversion from one type to another is ever performed -- the standard
- procedures SHORT and LONG should be used to convert between these
- types.
-
- Constants of type LONGREAL are no different from REAL constants. The
- type of the constant is determined by context. You may, however,
- "type" a constant by the use of the SHORT or LONG procedure. Ex:
-
- CONST longreal1 = LONG(1.0);
-
-
- 4.7.3 Additional or augmented standard procedures
-
-
- 4.7.3.1 NEW and DISPOSE -- pointer argument.
-
- NEW and DISPOSE have been deleted from the language definition in the
- 3rd edition of Wirth's book. We implement them thus:
-
- NEW(p)
-
- Invokes the procedure ALLOCATE, which must conform to the type:
-
- PROCEDURE ( VAR ADDRESS, CARDINAL )
-
- passing along p and the size of the object p is defined as pointing
- to.
-
- DISPOSE(p)
-
- Invokes the procedure DEALLOCATE, which must conform to the type:
-
- PROCEDURE ( VAR ADDRESS, CARDINAL )
-
- passing along p and the size of the object p is defined as pointing
- to.
-
- The procedures ALLOCATE and DISPOSE must, therefore, be defined in the
- module using NEW and/or DISPOSE, or imported from some other module,
-
-
-
- The Compiler 22
-
-
- like Storage.
-
-
-
-
- 4.7.3.2 LONG and SHORT
-
- PROCEDURE LONG( INTEGER ) :LONGINT;
-
- PROCEDURE LONG( CARDINAL ) :LONGCARD;
-
- PROCEDURE LONG( REAL ) :LONGREAL;
-
- PROCEDURE SHORT( LONGINT ) :INTEGER;
-
- PROCEDURE SHORT( LONGCARD ) :CARDINAL;
-
- PROCEDURE SHORT( LONGREAL ) :REAL;
-
- LONG takes an INTEGER, CARDINAL or REAL and converts it into a LONGINT
- LONGCARD or LONGREAL, respectively.
-
- SHORT takes a LONGINT, LONGCARD or LONGREAL and converts it into an
- INTEGER, CARDINAL or REAL, respectively.
-
-
-
-
- 4.7.3.3 FLOAT and TRUNC
-
- With our two integer/cardinal and real sizes, here is the behavior of
- the TRUNC and FLOAT procedures.
-
- PROCEDURE FLOAT( CARDINAL ) :REAL;
-
- PROCEDURE FLOAT( LONGCARD ) :LONGREAL;
-
- PROCEDURE TRUNC( REAL ) :CARDINAL;
-
- PROCEDURE TRUNC( LONGREAL ) :LONGCARD;
-
-
-
-
-
-
- 4.8 Objects exported by the pseudo module SYSTEM
-
-
- 4.8.0.1 TYPE BYTE
-
- Takes 1 byte of storage. Only assignment is defined for this type.
- If the formal parameter of a procedure is of type BYTE, the
-
-
-
- The Compiler 23
-
-
- corresponding actual parameter may be of any type that takes 1 byte of
- storage.
-
- If the formal parameter of a procedure is of type ARRAY OF BYTE, the
- corresponding actual parameter may be of any type.
-
-
- 4.8.0.2 TYPE WORD
-
- Takes 1 word (2 bytes) of storage. Only assignment is defined for
- this type. If the formal parameter of a procedure is of type WORD,
- the corresponding actual parameter may be of any type that takes 1
- word of storage.
-
- If the formal parameter of a procedure is of type ARRAY OF WORD, the
- corresponding actual parameter may be of any type. Care should be
- taken in this case, as the size of the parameter passed is rounded up
- to an even size.
-
-
- 4.8.0.3 TYPE ADDRESS
-
- The type ADDRESS is compatible with all pointer types. ADDRESS itself
- is defined as a POINTER TO WORD. In this implementation, the type
- ADDRESS is not compatible with any arithmetic type. This is due to
- the fact that the Intel 8086 series processors use segmented
- addresses. It would not be hard to implement automatic conversions
- between LONGCARD and ADDRESS but it is felt that this would be
- contrary to the spirit of the language, whereby the compiler is not
- expected to perform any "magic" tricks. Instead, two functions are
- provided for that purpose: FLAT and PTR.
-
- In release 1.2 we relaxed the above a little. ADDRESS + CARDINAL and
- ADDRESS - CARDINAL are legal expressions. The CARDINAL is added or
- subtracted from the offset portion of the ADDRESS and the result is
- still an ADDRESS.
-
- Also, INC and DEC can take an ADDRESS as their first argument. The
- operation is, however, performed on the offset portion of the ADDRESS
- only.
-
-
-
-
- 4.8.0.4 SEG and OFS
-
- These are field definitions for POINTER types. If you import these,
- you may access the segment or offset portions of a pointer variable
- using regular field selection syntax. Example
-
- pointer.SEG :segment portion of pointer
-
-
-
-
-
- The Compiler 24
-
-
- 4.8.0.5 PROCEDURE ADR
-
- ADR( designator ) Returns the address of designator (type ADDRESS).
-
-
- 4.8.0.6 PROCEDURE FLAT
-
- FLAT( ADDRESS ) returns a LONGCARD "flat" address.
-
-
- 4.8.0.7 PROCEDURE PTR
-
- PTR( LONGCARD ) returns an ADDRESS corresponding to the "flat" address
- represented by the LONGCARD.
-
-
- 4.8.0.8 PROCEDURE SEGMENT
-
- SEGMENT( designator ) returns the segment portion of the address of
- 'designator'. Example:
-
- DX := SEGMENT( buffer ); would assign to DX the segment value of
- ADR(buffer).
-
-
- 4.8.0.9 PROCEDURE OFFSET
-
- OFFSET( designator ) returns the offset portion of the address of
- 'designator'.
-
-
- 4.8.0.10 PROCEDURE NEWPROCESS
-
- NEWPROCESS(p:PROC; a:ADDRESS; n:CARDINAL; VAR p1:ADDRESS)
-
- creates a new process whose entry point is p and workspace is at a for
- n bytes. p1 is the new process pointer. This process is not
- activated until a TRANSFER to p1 is done.
-
- The starting priority of the new process is the current processor
- priority at the time NEWPROCESS is invoked (please refer to the
- section on Module Priorities).
-
-
- 4.8.0.11 PROCEDURE TRANSFER
-
- TRANSFER( VAR p1, p2 :ADDRESS)
-
- suspends the current process, assigning it to p1 and resumes p2. The
- current process' value is assigned to p1 only after p2 has been
- identified; it is, therefore, okay for p1 and p2 to be the same.
-
- The process is resumed at the same priority level that it was running
-
-
-
- The Compiler 25
-
-
- at, at the time of suspension.
-
-
- 4.8.0.12 PROCEDURE IOTRANSFER
-
- IOTRANSFER( VAR p1, p2 :ADDRESS; intVector :CARDINAL )
-
- issues a TRANSFER from p1 to p2 (just the way TRANSFER does it) after
- installing the current process for reactivation when an interrupt
- comes in through interrupt vector intVector.
-
- When the interrupt occurs, the interrupt vector is reloaded with its
- previous value. A TRANSFER is done to the I/O process (the one that
- issued the IOTRANSFER) such that p2 now contains the value of the
- process that was running when the interrupt occurred.
-
-
- 4.8.0.13 ASSEMBLER
-
- An 8086 inline assembler is provided. Once ASSEMBLER is imported from
- SYSTEM, you can enter inline assembler code by bracketing it with the
- keywords ASM and END.
-
- Assembler input is free form. Comments are entered as in regular
- Modula-2. Example
-
- loop: CMP BYTE [SI], 0 (*end of string?*)
- MOV BYTE [DI], [SI]
- INC SI INC DI (*increment pointers*)
- JMP loop
-
- The assembler accepts all the 8086/8088 opcode mnemonics. Address
- operands can be coded in just about any form acceptable to other
- assemblers, except that the only operator supported if '+'. Operand
- type overrides are: WORD, BYTE, FAR, NEAR and are not to be followed
- by the keyword POINTER or PTR. Example
-
- label: MOV AX, ES:[BX,DI+5]
- MOV AX, ES:5[DI+BX]
- MOV WORD [5], 1
- CALL NEAR [DI]
- TEST BYTE i+2, 1
-
- All the mnemonics and register names must be entered in upper case.
- In case you need to use a Modula-2 name that conflicts with one of the
- assembler reserved symbols, you may precede it with a '@'. Example
-
- MOV @AX, AX
-
- would generate a move from register AX to variable AX.
-
- All modula-2 variables can generally be accessed in assembler. Record
- field names are not accessible from assembler. The assembler will not
-
-
-
- The Compiler 26
-
-
- automatically do anything for you. For example: if you specify a VAR
- parameter as an operand to an instruction, you are naming the address
- of the pointer to the actual parameter. Example
-
- PROCEDURE p( VAR done :BOOLEAN );
- ...
- ASM
- LES DI, done
- MOV BYTE ES:[DI], TRUE
- END;
-
- is the correct way of storing TRUE in done.
-
- The following types of constants may be accessed in assembler:
- INTEGER, CARDINAL, BOOLEAN, CHAR and enumeration constants.
-
- All labels declared inside an ASM section are local to that section of
- code. But labels names cannot match some name known in the scope of
- the current procedure. Labels can only be referenced in jump
- instructions.
-
- All jumps are optimized by the compiler. There is, therefore, no need
- (or capability) to specify the size of a jump. In particular, the
- compiler will turn a conditional jump out of range into a reverse
- conditional jump over a far jump to the original destination.
-
- Remember, this is a Modula-2 compiler, not an assembler! The inline
- assembler capability is provided for use in exceptional situations
- only.
-
-
-
-
- 4.8.0.14 ASSEMBLER - 8087 support
-
- All the 8087 math coprocessor instructions are supported by the inline
- assembler. There are some restrictions, however.
-
- Only the following operand types are supported by the load and store
- instructions: INTEGER, LONGINT, REAL and LONGREAL. You may not,
- therefore, load or store a value in temporary real or decimal format.
-
- The meaning of the "no operand" form of the arithmetic instructions
- was retained:
-
- FADD, FSUB, FMUL and FDIV all operate on the two top elements of
- the 8087 stack, using ST(1) as the destination and removing ST.
-
- FSUBR subtracts ST(1) from ST (FDIVR divides ST by ST(1)),
- leaving the result in ST(1) and removing ST.
-
- The 2 operand format of the arithmetic instructions was not
- implemented. You may not, therefore, specify a destination register
-
-
-
- The Compiler 27
-
-
- other than ST, except in the "and pop" versions of the instructions.
-
- With a regular assembler, in register to register operations, you can
- specify the register that gets the result of the operation (the
- destination register). By definition, the destination register is
- also the first operand of the instruction.
-
- With our inline assembler, ST is always the destination of the
- operation, except in the "and pop" form of the instructions, in which
- case the register specified in the instruction "gets the result".
-
- For consistency, we decided that ST should always be the first operand
- of the instruction, even when the "and pop" form is used.
-
- The meaning of FSUBP, FSUBRP, FDIVP and FDIVRP is, therefore:
-
- FSUBP ST(1) means FSUBRP ST(1),ST -> ST(1):=ST-ST(1)
-
- FSUBRP ST(1) means FSUBP ST(1),ST -> ST(1):=ST(1)-ST
-
- FDIVP ST(1) means FDIVRP ST(1),ST -> ST(1):=ST/ST(1)
-
- FDIVRP ST(1) means FDIVP ST(1),ST -> ST(1):=ST(1)/ST
-
- and ST is popped.
-
-
-
-
-
-
- 4.9 The generated object code
-
-
-
-
-
- 4.9.1 Data type representation
-
- CHAR 1 byte
-
- INTEGER 2 bytes 2's complement
-
- CARDINAL 2 bytes
-
- LONGCARD 4 bytes
-
- LONGINT 4 bytes 2's complement
-
- BOOLEAN 1 byte (1=TRUE, 0=FALSE)
-
- REAL 4 bytes Intel 8087 format.
-
-
-
-
- The Compiler 28
-
-
- LONGREAL 8 bytes Intel 8087 format.
-
- BITSET 1 word. 0 is low order bit, 15 is high order bit.
-
- Enumerations 1 byte
-
- SETs 1 to 8 words (sets of up to 256 elements)
-
- POINTERs 4 bytes in Intel 8086/88 format
-
- PROCEDUREs 4 bytes POINTER to procedure entry point
-
- Addresses are represented in the default Intel 8086 format:
-
- 1 word byte offset
-
- 1 word segment
-
- Numeric values are likewise represented the way the Intel 8086
- processor family likes them: low order byte first, high order byte
- last.
-
-
-
-
- 4.9.2 The runtime memory map
-
- Currently, the compiler generates code using the "large" or "huge"
- memory model only.
-
- In the "huge" memory model, each module has its own data and code
- segments.
-
- In the "large" memory model, each module has its own code segment.
- The entire program has one data segment.
-
- The linker binds all the code segments first, and then all the data
- segments. The stack is allocated above the data segments. All the
- remaining memory is available for the heap.
-
- When a program is loaded for execution, here is what the memory looks
- like:
-
-
- From low to high addresses:
-
- 0 ----------------------------------------------
- I Interrupt vectors I
- I DOS I
- PSP I Program segment prefix I
- PSP+100h I Program Code segments I
- I Program Data segment(s) I
- StackSeg I Stack I
-
-
-
- The Compiler 29
-
-
- HeapTop I Heap I
- I ... I
- I DOS Command (resident portion) I
- MemTop ----------------------------------------------
-
- Label names on the left are the ones exported by System.
-
- This system uses interrupt vector 192 (0C0H) at location 0000:0300.
- Interrupt 192 is issued by a program when a runtime error occurs, when
- HALT is invoked or when a coroutine other than the main one terminates
- via a return.
-
- The first word (offset 0) in every code segment contains the data
- segment value for that particular module (for the program, in the case
- of the "large" memory model.
-
-
- 4.9.3 Procedure calling conventions
-
- Procedure parameters are pushed into the stack 1st argument first.
- Control is then transferred to the procedure through a FAR call. It
- is the called procedure's responsibility to remove its parameters from
- the stack before returning.
-
-
-
-
- 4.9.3.1 Parameter passing (all except open array parameters)
-
- If the formal parameter of a procedure is a value parameter, the
- actual parameter is copied into the stack.
-
- If the formal parameter is a variable parameter (VAR), the address of
- the actual parameter is pushed into the stack (first the segment
- portion of the address and then the offset part).
-
-
-
-
- 4.9.3.2 Parameter passing (open array parameters)
-
- If the formal parameter is an open array, the address and HIGH value
- of the corresponding formal parameter are pushed into the stack (HIGH
- value first, and then the address, as above).
-
- If the open array parameter is a value parameter, the value of the
- actual parameter is copied into the stack on procedure entry.
-
-
-
-
- 4.9.3.3 Returning values from a function procedure
-
-
-
-
- The Compiler 30
-
-
- One byte results are returned in AL, two byte results are returned in
- AX, and four byte results are returned in DX:AX (DX has the high order
- part of the result).
-
- LONGREALs are returned in the stack, at a location reserved for that
- purpose by the caller. When invoking a function that returns a
- LONGREAL, an extra parameter is pushed onto the stack: the two byte
- offset, in the SS segment, of where to place the result. This choice
- will make it easy to allow for the return of arbitrary structures from
- a function, should the language standard go that way, while at the
- same time allowing for full reentrancy of the code generated.
-
-
-
-
-
-
- 4.10 Module priorities
-
-
- Eight module priority levels are supported in this implementation,
- from 0 (highest priority) to 7 (lowest).
-
- Priorities are implemented by masking off, on the 8259 interrupt
- controller, all the interrupts at or below the current priority
- level.
-
- Because the PC usually runs with several of the interrupt levels
- disabled, it is not easy to decide what the interrupt mask for the
- value for "no priority" should be for your particular application.
- The implementation of NEWPROCESS, therefore, assumes that you have
- enabled all the interrupts that your program will be capable of
- processing before you create your processes. The value in the
- interrupt mask register of the 8259 at the time of process creation
- will determine the initial priority level of this process, once it
- gets started. Because of this, invoking NEWPROCESS from inside a
- priority module is usually not what you want to do!
-
- Execution priorities are changed when entering/exiting procedures in
- modules that have a priority specification, and during the execution
- of some form of a TRANSFER.
-
- We highly recommend that you study the communications program
- provided, paying particular attention to the module Kernel, for an
- example of how to use priorities with this system.
-
- NOTE: The compiler does not restrict the priority level specified (any
- number will do). You must, therefore, exercise care in defining a
- module's priority level. On the other hand, it is easy to add
- additional priority levels by simply modifying the runtime module
- M2Procs.
-
-
-
-
-
- The Compiler 31
-
-
-
-
-
-
- 4.11 Memory models
-
-
- In general, you may compile the same code under either the LARGE or
- the HUGE memory model.
-
- The only factor to consider is when using inline assembler.
-
- Under the HUGE memory model, the compiler generates code to reload DS
- after any invocation of an imported procedure or a VARiable
- procedure. Under the LARGE memory model, this is not necessary as a
- single data segment is defined. If you write some inline assembler
- code that modifies DS, please restore it, even if the next thing you
- do is a RETurn; this way, your routine will work regardless of whether
- you use the LARGE or the HUGE memory model.
-
- Under the HUGE memory model, access to external variables is done
- through an indirect pointer, whereas in the LARGE memory model the
- external variable resides in the program's ONLY data segment and is,
- therefore, directly accessible.
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Using OBJ files 32
-
-
-
-
-
-
-
-
- Chapter 5
-
- Using OBJ files
-
-
-
- As long as you use this system to write Modula-2 programs for the DOS
- environment only, there is virtually no reason to use OBJ files. But,
- in case you have to...
-
- You condition the compiler to generate OBJ files by setting the
- environment variable M2OUPUT to OBJ.
-
- set M2OUTPUT=OBJ
-
- To link OBJ files you must exit the MC environment (or invoke the DOS
- shell) and use some OBJ file linker.
-
- Also, with OBJ files, there is no module version checking done for
- you. Of course, if you keep your ".MAK" files up to date, you should
- not encounter any problems.
-
-
-
-
-
-
- 5.1 GenLink
-
-
- To help you figure out which files need to be linked, we provide a
- utility (GenLink) that generates a LINK answer file. The LINK answer
- file created by GenLink lists all the Modula-2 OBJ files that are
- required to link your program.
-
- Since your program, most likely, requires modules written in another
- language (or you would not be using OBJ files, right?!), you will have
- to edit the file created by GenLink to make it suitable for the job at
- hand.
-
-
-
-
-
-
- 5.2 Foreign Modules
-
-
-
-
- Using OBJ files 33
-
-
-
-
- To let the Modula-2 compiler know about modules written in other
- languages, you must write FOREIGN DEFINITION modules. A foreign
- definition modules is a regular definition module, with the exception
- of the module's header, which goes like this:
-
- FOREIGN [C|PASCAL] DEFINITION MODULE modName;
-
- where the 'C' or 'PASCAL' qualifier is optional.
-
-
-
-
- 5.2.1 External names
-
- Names of public variables and procedures in foreign modules are
- encoded in one of 3 ways:
-
- In a regular FOREIGN (neither C nor PASCAL) module, the
- identifiers are encoded in the object files as you enter them.
-
- In a FOREIGN C module, identifiers are written out preceded by a
- '_' character.
-
- In a FOREIGN PASCAL module, identifiers are converted to all
- upper case.
-
- WARNING: As currently implemented, SET and STRING constants defined in
- a FOREIGN DEFINITION module, cause the compiler to generate external
- references to these. These "constants" should, therefore, be
- allocated space and properly initialized in the foreign module.
-
-
-
-
- 5.2.2 Implementation
-
- FOREIGN modules are not expected to have an initialization procedure,
- and the compiler will not generate these initialization calls, as in
- the case of regular Modula-2 modules.
-
-
-
-
- 5.2.2.1 FOREIGN C modules
-
- When invoking a routine defined in a FOREIGN C module, the arguments
- are pushed onto the stack in reverse order, as per C's custom. Also,
- the caller will remove the arguments off the stack upon return from
- the subroutine.
-
- Since C, unlike Modula-2, supports (?) the passing of a variable
-
-
-
- Using OBJ files 34
-
-
- number of arguments to a function, the symbol '...' may be used at the
- end of a PROCEDURE parameter list definition to indicate that an
- indeterminate number of arguments may be passed. Example:
-
- PROCEDURE sum( n:INTEGER; ... ) :INTEGER;
-
- defines a function that takes n integers and returns their sum. It
- could, actually, be implemented in Modula-2 thus:
-
- PROCEDURE sum( n:INTEGER; ... ) :INTEGER;
- VAR p :POINTER TO INTEGER;
- res :INTEGER;
- BEGIN
- res := 0;
- p := ADR(n) + 2;
- WHILE n > 0 DO
- res := res + p^;
- INC( p, 2 );
- DEC( n );
- END;
- RETURN res;
- END sum;
-
- Good luck!
-
- In addition to being useful to define functions that take a variable
- number of parameters, the use of '...' is also a handy (?!) way of
- improving the odds that the arguments are passed in a form that C will
- like.
-
-
-
-
- 5.2.2.2 Parameter passing
-
- The form in which the individual parameters are passed is always the
- same, regardless of whether the procedure is in a foreign module or
- not. The exception is when you use '...'.
-
- When passing parameters that correspond to the '...' in the procedure
- heading, the compiler follows the default C rules: Everything is
- passed by value, except for arrays, which are passed by reference
- (their address, instead of their value, is pushed onto the stack).
-
- Modula-2 does not allow functions to return structured types. Some C
- compilers return structured values by actually returning a pointer to
- those values in the DX:AX register pair, which is just the way that
- Fitted Modula-2 returns pointers! With these, therefore, you could
- define
-
- struct someStruct cfunct()
-
- as
-
-
-
- Using OBJ files 35
-
-
-
- TYPE someStructPtr = POINTER TO someStruct;
- PROCEDURE cfunct() :someStructPointer;
-
-
-
-
- 5.2.3 In the real world...
-
- Knowing the parameter passing conventions used by the compiler you
- should have no trouble writing assembly language modules to be invoked
- by Modula-2.
-
- With the help provided (FOREIGN C and '...'), it should be easy enough
- to interface Modula-2 to C. But is it, really? Not quite!
-
- There are two main problems that you will have to overcome. One, is
- the choice of a suitable memory model. Our LARGE memory model is
- probably a better choice than HUGE, as some compilers require DS to
- always point to DGROUP.
-
- The other problem, is the set of requirements imposed by each
- language's runtime system. Since we provide all the source code for
- our runtime, your best bet will probably be to modify our system to
- suit theirs. Modules that are obvious candidates for "adaptation" are
- System and Storage; In their current state, they are virtually
- guaranteed to not work with another vendor's runtime system, and they
- are a base on which many other library modules depend.
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- The Text Editor 36
-
-
-
-
-
-
-
-
- Chapter 6
-
- The Text Editor
-
-
-
- The text editor included in this package has all the features that you
- have come to expect from a basic program editor: the ability to
- insert, delete, move, find and replace text; support for concurrent
- editing of multiple files (as many as will fit in memory) in separate
- windows (as many as will fit on the screen) with the ability to copy
- or move text from window to window.
-
- Although you may load the same file in two different windows, the
- editor will not be aware of the fact and will treat the two copies as
- two different files.
-
- The only preset limitation in the editor is that it cannot handle
- files bigger than 64k. This decision was justified by the fact that
- Modula-2 programs are supposed to be modular. File load/save speed
- was the overriding factor here.
-
- All the text editor keys are defined by the user through the use of
- the EDCONFIG program. When the editor starts, it expects to find the
- file M2ED.CFG in the current PATH.
-
- M2ED.CFG will also tell the editor what display colors (attributes) to
- use for the Status line, for Normal text and for Marked text blocks.
-
- Finally, M2ED.CFG also contains the default settings for the TAB size
- value, as well as whether or not the editor will expand the tabs
- inserted into the text spaces. Note: Tabs present in a file will not
- be expanded to spaces by the editor.
-
- To get you started, we provide a M2ED.CFG file with the following
- definitions:
-
- Cursor left : Left
- Cursor right : Right
- Cursor up : Up
- Cursor down : Down
- Previous word : ^Left
- Next word : ^Righ
- Page up : PgUp
- Page down : PgDn
- Cursor to beginning of line : Home
- Cursor to end of line : End
-
-
-
- The Text Editor 37
-
-
- Cursor to top of window : ^Home
- Cursor to bottom of window : ^End
- To beginning of file : ^PgUp
- To end of file : ^PgDn
- Current line to top of window : AltT
- Toggle insert/overtype : Ins
- Delete character under cursor : Del
- Delete previous character : ^H
- Delete Current Line : ^Y
- Delete to EOL : AltY
- Delete Word : ^D
- Indent Line : F4
- Unindent Line : F3
- Indent Block : Alt=
- Unindent Block : Alt-
- New file : AltN
- Read file : AltR
- Write block : AltW
- Save file : AltS
- Open window : ^O
- Close Window : ^C
- Next window : F2
- Previous window : aF2
- Split screen : ^S
- Mark beginning of block : F7
- Mark end of block : F8
- Goto beginning of block : AltB
- Goto end of block : AltE
- Clear block marks : AltH
- Copy block : AltC
- Delete block : AltD
- Move block : AltM
- Search forward : F5
- Search backwards : aF5
- Replace forward : F6
- Replace backwards : aF6
- Global replace : ^F6
- Repeat last search/replace : F1
- Goto next error : ^E
- Goto previous error : ^P
- Goto line : AltG
- Set options : AltO
- Redraw the screen : ^L
- Quit : AltQ
-
-
-
-
-
-
-
-
-
-
-
-
- The Linker 38
-
-
-
-
-
-
-
-
- Chapter 7
-
- The Linker
-
-
-
- The linker is invoked by the command line
-
- M2LINK myprog [/s n] [/h n] [/o] [/l] [/v] [/swap [path]]
-
- where 'myprog' is the main module of the program you are creating.
- The options are thus:
-
- /s n n is the size of the stack to allocate (default is
- 8192).
-
- /h n n is the amount of space to reserve for the heap (in
- paragraphs). The default is all the free memory.
-
- /o invokes the optimizer. The optimizer prevents the
- output, to the object file, of all the procedures
- that are part of included modules but are not
- referenced. This will make your final EXE files
- smaller. This option (/o) and /l are mutually
- exclusive; The last one seen on the command line is
- the one that takes precedence.
-
- /l tells the linker to process the line number
- information in the .M2O files and include it in the
- .DBG file. This option (/l) and /o are mutually
- exclusive; The last one seen on the command line is
- the one that takes precedence.
-
- /k tells the linker to ignore module keys, i.e. to not
- check for module version compatibility. This option
- should be used with extreme care.
-
- /v enables verbose mode (which was the default in older
- versions of the linker).
-
- /swap [path] tells the linker to use a swap file. Code segments
- will be kept in this swap file instead of in main
- memory during the link process. This allows you to
- link larger programs.
-
- The linker creates two files: the .EXE file is your executable
- program, the .DBG file is a file containing symbol information for use
-
-
-
- The Linker 39
-
-
- by other utilities (see Map file generator, Profiler).
-
- If the /swap directive is used, a swap file is created. You may
- select the path (drive:directory) where the swap file is to be
- created. Example:
-
- M2LINK myprog /swap D:
-
-
-
-
- 7.1 Module keys
-
-
- The module header record and the import records written out by the
- compiler to the object file are stamped with the date of the .DEF file
- that was processed - this becomes the module key. The linker will
- assure that these module keys in the module header of the imported
- module and in the import record match; If they do not match, both
- modules were not compiled using the same definition module.
-
- Because of the use of module keys, it is imperative that the date of
- the distributed .DEF files not be modified unless you intend to
- recompile the implementation modules.
-
- When using OBJ files, you do not have the protection of Module keys.
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Other utilities 40
-
-
-
-
-
-
-
-
- Chapter 8
-
- Other utilities
-
-
-
-
-
-
-
-
- 8.1 Editor configurator
-
-
- This program lets you define the keystrokes to be used to invoke all
- the editor commands, the screen attributes (colors) to use, and the
- default editor options.
-
- Invocation:
-
- EDCONFIG
-
- EdConfig presents you with a menu from which you may elect to modify
- the default editor options, the display attributes, or configure the
- editor commands.
-
- If you are creating a new configuration file, you must configure the
- editor commands.
-
- If you chose to configure the editor commands, you will be prompted
- for a log file (default M2ED.HLP), a text file in which all of your
- command choices will be saved. You may print this file to create a
- quick reference card. EDCONFIG will then prompt you for the key
- sequence to be used for each editor command. For each command,
- EDCONFIG will also give you the option of defining an alternate key
- sequence.
-
- When you select Quit, the program will prompt you for an output file,
- the default being 'M2ED.CFG'.
-
-
-
-
-
-
- 8.2 Map file generator
-
-
-
-
- Other utilities 41
-
-
-
-
- Invocation:
-
- DBG2MAP program_name
-
- Reads the .DBG file created by M2LINK and creates a DOS LINK
- compatible .MAP file.
-
-
-
-
-
-
- 8.3 Make and the Makefile generator
-
-
- These utilities eliminate the burden, on the user's part, of having to
- figure out which modules are affected and, therefore, need to be
- recompiled as a result of any changes to particular definition
- modules.
-
- GENMAKE creates the .MAK file, the file with all the dependencies
- (this is the hard part) whereas MAKE (built into the compiler) will
- insure that these dependencies are observed when updating the object
- files.
-
- GENMAKE Invocation:
-
- GENMAKE main_module_name [/l] [/obj]
-
- generates the .MAK file containing all the module dependencies for the
- named program. It does this by reading all the IMPORT statements in
- the main module and, recursively, generating the dependency lists for
- all those modules. GENMAKE will indeed read all the .MOD and .DEF
- files involved.
-
- The /l option instructs GenMake to include the directories listed in
- the environment variable M2LIB in its search path. Otherwise, only
- the modules in the current directory will be taken into consideration
- when creating the makefile.
-
- The /obj option tells GenMake that you will be using the compiler to
- generate OBJ files instead of M2O files.
-
- MAKE invocation: see "Running the Compiler".
-
- MAKE will invoke the compiler as needed to assure that all the
- dependencies in the make file are observed. MAKE is dumb in that it
- will just run through the makefile sequentially. It was GENMAKE's
- responsibility to see that the dependencies are listed in a proper
- sequence. Please keep this in mind if you should edit a makefile!
-
-
-
-
- Other utilities 42
-
-
-
-
-
-
-
- 8.4 M2O file decoder
-
-
- Invocation:
-
- DECODE module_name
-
- Decodes a .M2O file sending the output to the terminal.
-
-
-
-
-
-
- 8.5 The execution profiler
-
-
- Invocation:
-
- M2PROF program_name
-
- The profiler will ask you for the name of the .DBG file to use (if it
- cannot find it) and give you an option of profiling your entire
- program (generating an execution profile by module), a particular
- module (generating an execution profile by procedure in that module)
- or a particular procedure (generating an execution profile by line in
- the procedure).
-
- Upon program termination, the profiler outputs the list of all the
- modules/procedures/lines profiled, ranked by execution time, to a file
- of your choice.
-
- This profiler is not that versatile, but it is useful nevertheless.
- It proved instrumental in pinpointing some obvious areas for
- improvement in the compiler (Oh, we did not tell you, did we? This
- compiler was written in the language it compiles -- Modula-2 -- and
- this system was used as our primary development tool since very early
- in the development process).
-
-
-
-
-
-
-
-
-
-
-
-
-
- The Library Modules 43
-
-
-
-
-
-
-
-
- Chapter 9
-
- The Library Modules
-
-
-
- For complete information on what each library module provides, as well
- as its proper usage, please refer to the .DEF files.
-
- In addition, the source code of all the library modules is available
- to all the registered users (see the order form in the back of this
- document for details).
-
-
-
-
-
-
- 9.1 Release 3.0 libraries
-
-
- We have not created any source level incompatibility with previous
- library modules, that we are aware of. But you will have to recompile
- all your programs, as they will not link with the new library
- modules.
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- The runtime support system 44
-
-
-
-
-
-
-
-
- Chapter 10
-
- The runtime support system
-
-
-
- The library module System contains the runtime system's initialization
- code. In particular, special interrupt vectors are loaded with the
- addresses of routines (also in System) that will handle runtime errors
- and other abnormal program terminations. In addition, the module
- Storage depends on System doing its stuff -- setting the HeapBase,
- HeapTop and MemTop variables.
-
- Three other special modules are included in this package. M2Reals,
- M2Longs and M2Procs. These modules provide support for specific
- language features.
-
- M2Reals handles all the REAL and LONGREAL arithmetic and conversions.
- In release 2, M2Reals checks for the presence of an 8087 math
- co-processor and uses it, if found.
-
- M2Longs handles LONGINT and LONGCARD arithmetic.
-
- M2Procs provides the coroutine support.
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Modula-2 Syntax 45
-
-
-
-
-
-
-
-
- Chapter 11
-
- Modula-2 Syntax
-
-
-
-
- ident = letter {letter | digit}.
- number = integer | real.
- integer = digit {digit} | octalDigit {octalDigit} ("B"|"C") |
- digit {hexDigit} "H".
- real = digit {digit} "." {digit} {ScaleFactor}.
- ScaleFactor = "E" ["+"|"-"] digit {digit}.
- hexDigit = digit | "A" | "B" | "C" | "D" | "E" | "F".
- digit = octalDigit | "8" | "9".
- octalDigit = "0" | "1" | "2" | "3" | "4" | "5" | "6" | "7".
- string = "'" {character} "'" | '"' {character} '"' .
- qualident = ident {"." ident}.
- ConstantDeclaration = ident "=" ConstExpression.
- ConstExpression = expression.
- TypeDeclaration = ident "=" type.
- type = SimpleType | ArrayType | RecordType | SetType |
- PointerType | ProcedureType.
- SimpleType = qualident | enumeration | SubrangeType.
- enumeration = "(" IdentList ")".
- IdentList = ident {"," ident}.
- SubrangeType = [ident] "[" ConstExpression ".." ConstExpression "]".
- ArrayType = ARRAY SimpleType {"," SimpleType} OF type.
- RecordType = RECORD FieldListSequence END.
- FieldListSequence = FieldList {";" FieldList}.
- FieldList = [IdentList ":" type |
- CASE [ident] ":" qualident OF variant {"|" variant}
- [ELSE FieldListSequence] END].
- variant = [CaseLabelList ":" FieldListSequence].
- CaseLabelList = CaseLabels {"," CaseLabels}.
- CaseLabels = ConstExpression [".." ConstExpression].
- SetType = SET OF SimpleType.
- PointerType = POINTER TO type.
- ProcedureType = PROCEDURE [FormalTypeList].
- FormalTypeList = "(" [ [VAR] FormalType
- {"," [VAR] FormalType} ] ")" [":" qualident].
- VariableDeclaration = IdentList ":" type.
- designator = qualident {"." ident | "[" ExpList "]" | "^"}.
- ExpList = expression {"," expression}.
- expression = SimpleExpression [relation SimpleExpression].
- relation = "=" | "#" | "<" |"<=" | ">" | ">=" | IN.
- SimpleExpression = ["+"|"-"] term {AddOperator term}.
-
-
-
- Modula-2 Syntax 46
-
-
- AddOperator = "+" | "-" | OR.
- term = factor {MulOperator factor}.
- MulOperator = "*" |"/" | DIV | MOD | AND.
- factor = number | string | set | designator [ActualParameters] |
- "(" expression ")" | NOT factor.
- set = [qualident] "{" [element {"," element}] "}".
- element = expression [".." expression].
- ActualParameters = "(" [ExpList] ")" .
- statement = [assignment | ProcedureCall |
- IfStatement | CaseStatement | WhileStatement |
- RepeatStatement | LoopStatement | ForStatement |
- WithStatement | EXIT | RETURN [expression] ].
- assignment = designator ":=" expression.
- ProcedureCall = designator [ActualParameters].
- StatementSequence = statement {";" statement}.
- IfStatement = IF expression THEN StatementSequence
- {ELSIF expression THEN StatementSequence}
- [ELSE StatementSequence] END.
- CaseStatement = CASE expression OF case {"|" case}
- [ELSE StatementSequence] END.
- case = [CaseLabelList ":" StatementSequence].
- WhileStatement = WHILE expression DO StatementSequence END.
- RepeatStatement = REPEAT StatementSequence UNTIL expression.
- ForStatement = FOR ident ":=" expression TO expression
- [BY ConstExpression] DO StatementSequence END.
- LoopStatement = LOOP StatementSequence END.
- WithStatement = WITH designator DO StatementSequence END .
- ProcedureDeclaration = ProcedureHeading ";" block ident.
- ProcedureHeading = PROCEDURE ident [FormalParameters].
- block = {declaration} [BEGIN StatementSequence] END.
- declaration = CONST {ConstantDeclaration ";"} |
- TYPE {TypeDeclaration ";"} |
- VAR {VariableDeclaration ";"} |
- ProcedureDeclaration ";" | ModuleDeclaration ";".
- FormalParameters =
- "(" [FPSection {";" FPSection}] ")" [":" qualident].
- FPSection = [VAR] IdentList ":" FormalType.
- FormalType = [ARRAY OF] qualident.
- ModuleDeclaration =
- MODULE ident [priority] ";" [import] [export] block ident.
- priority = "[" ConstExpression "]".
- export = EXPORT [QUALIFIED] IdentList ";".
- import = [FROM ident] IMPORT IdentList ";".
- DefinitionModule = DEFINITION MODULE ident ";"
- {import} {definition} END ident "." .
- definition = CONST {ConstantDeclaration ";"} |
- TYPE {ident ["=" type] ";"} |
- VAR {VariableDeclaration ";"} |
- ProcedureHeading ";".
- ProgramModule = MODULE ident [priority] ";" {import} block ident ".".
- CompilationUnit = DefinitionModule | [IMPLEMENTATION] ProgramModule.
-
-
-
-
-
- Classes 47
-
-
-
-
-
-
-
-
- Chapter 12
-
- Classes
-
-
-
- Version 3 of the compiler has extensions intended to add support for
- object oriented programming (OOP) through the introduction of
- classes.
-
- These extensions to Modula-2 should not, of course, be used if program
- portability to other environments is desired.
-
- This design has not been widely tested, and is subject to change in
- future versions of the system.
-
- If you use classes, please share your experiences with us.
-
-
-
-
-
-
- 12.1 Highlights of the implementation
-
-
- Readers already familiar with OOP terminology will be keen to note the
- highlights of this implementation:
-
- OOP features are supported by the use of four new reserved words
- (CLASS, INHERIT, INIT and DESTROY), two new standard identifiers
- (SELF and MEMBER), and the Objects library module.
-
- Class definitions may appear in definition modules, leaving the
- details of the implementations to implementation modules.
-
- Class implementations may extend the class definition, adding new
- attributes and methods to the original definition.
-
- Only single inheritance is allowed (INHERIT) in this release.
-
- Methods declared in a class definition are virtual.
-
- Methods declared in a class implementation are static.
-
- All objects are dynamic, i.e. you must create all objects before
- using them. There is no automatic garbage collection, i.e. you
-
-
-
- Classes 48
-
-
- must explicitly dispose of objects when no longer required.
-
- Class implementations may define object constructor (INIT) and
- destructor (DESTROY) methods that are invoked automatically when
- an object is created (by NEW) or destroyed (by DISPOSE).
-
- Local classes may be implemented within program and
- implementation modules. In such cases, the class implementation
- is also its definition (in an analogous manner to local modules
- not requiring a separate definition).
-
- Classes cannot, however, be implemented inside local (nested)
- modules.
-
-
-
-
-
-
- 12.2 Classes, attributes, methods, inheritance and polymorphism
-
-
- This section aims to give a very brief introduction to the terminology
- and ideas of object oriented programming (OOP) for new readers.
-
- Support for an "object" oriented paradigm of programming in Modula-2
- at the lowest level consists of allowing you to define object "types"
- (record, arrays, ...) and then to write procedures that manipulate
- parameters of those classes of objects. Thus we might have
-
- TYPE
- Gender = (male,female);
- Person = RECORD
- name : ARRAY [0..40] OF CHAR;
- sex : Gender;
- END;
-
- PROCEDURE IsMale (Human : Person) : BOOLEAN;
- BEGIN
- RETURN Human.sex = male
- END IsMale;
-
- In Modula-2 in particular, it is common to find all these related
- definitions encapsulated in a module. Indeed, one can go further, and
- hide the details of the type within the implementation; the library
- module Windows, for example, defines an opaque type Window and a bunch
- of procedures that operate on objects of that type (OpenWindow,
- SelectWindow, ... ).
-
- Once one has defined a type like Person, one can go on to use it in
- the definition of other types
-
- TYPE
-
-
-
- Classes 49
-
-
- Programmer = RECORD
- who : Person;
- favoriteLanguage : ARRAY [0..10] OF CHAR;
- END;
-
- and introduce other procedures to manipulate parameters of the
- Programmer type. But the awkward fact remains that, while in real
- life programmers are also persons, in Modula-2 variables of Programmer
- type are inherently incompatible with variables of Person type.
- Furthermore, if one wishes to hide the details of the types by
- defining them as opaque types, the mechanisms allowed depend heavily
- on awkward pointer manipulations.
-
- Thus it can be said that the methods traditionally used in Modula-2
- for program decomposition, while reducing the complexity of a total
- system, often tend to produce building blocks that are specific to the
- program at hand, and are reusable for other purposes only after a lot
- of extra effort has been put into modifying them. Re-using components
- often requires many textual changes, which can lead to an entire
- family of "similar" components that must all be managed and
- maintained.
-
- Enter the new OOP ideas! Better support for the paradigm is realized
- by extending the idea of a RECORD type to the idea of a CLASS type
-
- A Class is a new user defined type. A class defines both the
- "attributes" (fields) and "methods" (procedures) of the "instances"
- (objects) of that class; a CLASS declaration combines the declaration
- of an object's structure with the declaration of all the procedures
- (methods, in OOP terminology) that deal with that kind of object. An
- OOPed version of FileSystem might be introduced along these lines:
-
- DEFINITION MODULE OOPFileSystem;
- FROM SYSTEM IMPORT WORD;
- TYPE
- Response = ( done, notdone );
- IOMode = ( read, write, io );
- CLASS File;
- id :INTEGER;
- res :Response;
- eof :BOOLEAN;
- mode :IOMode;
- PROCEDURE Lookup(
- filename :ARRAY OF CHAR; new :BOOLEAN
- );
- PROCEDURE ReadWord( VAR w :WORD );
- PROCEDURE WriteWord( w :WORD );
- (*...*)
- END File;
- END OOPFileSystem.
-
- NOTE: In FileSystem.File there if a field 'fdptr' which is used to
- hold implementation specific information. This is not needed in
-
-
-
- Classes 50
-
-
- OOPFileSystem.File because we can add the needed fields to File in its
- implementation.
-
- This code actually gives the class definition rather than the class
- implementation -- the implementation would be elaborated in a
- corresponding implementation module. As usual, the definition gives
- all we need to know to be able to start using the class -- a program
- using OOPFileSystem might have code like:
-
- FROM OOPFileSystem IMPORT File;
- VAR
- f :File;
- w :WORD;
- BEGIN
- NEW(f); (* create an object of the File class *)
- f.Lookup( "myfile.txt", FALSE ); (* open file *)
- IF f.res = done THEN
- f.ReadWord( w );
- ...
-
- However, notice how we coded "f.ReadWord(w)" instead of
- "ReadWord(f,w)", and how we had to go further than just declare an
- instance f of the class File; we had to create the instance by calling
- NEW(f).
-
- So far this does not seem to have bought us much other than a
- syntactic change, writing code like f.ReadWord(w) in place of
- ReadWord(f, w). However, a very real advantage comes from being able
- to extend classes. Consider a class definition for a Person
-
- TYPE Gender = (unknown,male,female);
- CLASS Person;
- name :ARRAY [0..40] OF CHAR;
- sex :Gender;
- PROCEDURE isMale() :BOOLEAN;
- END Person;
-
- Notice that the method takes no parameter: the method will "know"
- about the object already, in distinction to the style used in writing
- traditional procedures.
-
- Programmers are also people, but they have further attributes and
- methods for dealing with them:
-
- TYPE LanguageName = ARRAY [0..10] OF CHAR;
- CLASS Programmer;
- INHERIT Person;
- favoriteLanguage :LanguageName;
- PROCEDURE isSmart() :BOOLEAN;
- END Programmer;
-
- Note the INHERIT clause: an object of the Programmer class is going to
- have all the attributes of a Person, and be subjectable to the methods
-
-
-
- Classes 51
-
-
- that can be applied to a Person -- as well as having new properties of
- its own. The Programmer class is said to be based on the Person
- class, or to be a "sub-class" or descendent of the Person
- "super-class" or ancestor..
-
- This implies that an object of the Programmer class is compatible to
- some degree with an object of a Person class -- even though it appears
- to be "bigger"!
-
- This guaranteed compatibility of derived data types with their base
- types lies behind the realization of an idea known as polymorphism.
- Some variables must be able to assume values of different (but
- related) data types at run time and, in the course of operations with
- objects, there must be the possibility of determining at run time the
- concrete actions to be executed (depending on the current dynamic data
- type of the object).
-
- All of this represents quite a departure from the very strict typing
- philosophy of Modula-2.
-
- Activating an operation with an object is often termed "sending a
- message to the object". The object reacts by executing a method. The
- assignment of methods to messages is determined for each class by the
- respective class definition, and the effect of sending a message
- differs from procedure invocations in conventional programming
- languages in that the determination of which method is to be executed
- can (and often must) occur at run time, rather than at compile time.
-
-
-
-
-
-
- 12.3 Defining classes in definition modules
-
-
- Time for some specifics that apply to this release of the compiler.
-
- A Class definition may appear in a definition module, where it
- specifies the format of the data to be allocated when an object of
- that class is later instantiated, and a set of methods (procedures)
- that are available to manipulate that object.
-
- A class definition is analogous to a type definition; the extended
- syntax for definitions in a definition module is described by
-
- definition = "CONST" {ConstantDeclaration ";"} |
- "TYPE" {ident ["=" type] ";"} |
- "VAR" {VariableDeclaration ";"} |
- "CLASS" ClassDefinition ";" |
- ProcedureHeading ";".
-
- ClassDefinition =
-
-
-
- Classes 52
-
-
- className ";"
- [ "INHERIT" someClassName; ]
- [ AttributeDeclarations ]
- { MethodDefinition }
- "END" className .
-
- AttributeDeclaration = { VariableDeclaration ";" } .
-
- MethodDefinition = ProcedureHeading .
- className = ident .
- someClassName = ident .
-
- An example of a Definition Module incorporating CLASS definitions is:
-
- DEFINITION MODULE People;
- TYPE Gender = (unknown,male,female);
- CLASS Person;
- name :ARRAY [0..40] OF CHAR;
- sex :Gender;
- PROCEDURE isMale() :BOOLEAN;
- END Person;
-
- TYPE LanguageName = ARRAY [0..10] OF CHAR;
- CLASS Programmer;
- INHERIT Person;
- favoriteLanguage :LanguageName;
- PROCEDURE isSmart() :BOOLEAN;
- END Programmer;
- END People.
-
- Notes:
-
- 1. The attributes are effectively the data fields of the class
- (object).
-
- 2. Methods are effectively procedures and, therefore, defined as
- such in an analogous way to defining other procedures exported
- from the module.
-
- 3. The methods are technically known as "virtual methods". An
- implementation of each one must be declared in the corresponding
- implementation module; however, this implementation may be
- overridden in classes derived from the one being defined.
-
- 4. An attribute of a class may be defined in terms of the class
- itself.
-
- For examples of this, please refer to the Lists example mentioned at
- the end of this chapter.
-
-
-
-
-
-
-
- Classes 53
-
-
-
-
-
-
- 12.4 Implementing classes in implementation modules
-
-
- A class defined in a definition module must, of course, be elaborated
- (its methods fully declared) in the corresponding implementation
- module. An implementation module or program module may also declare
- local classes.
-
- The syntax of declarations in this extension of Modula-2 is described
- by
-
- declaration =
- CONST {ConstantDeclaration ";"} |
- TYPE {TypeDeclaration ";"} |
- VAR {VariableDeclaration ";"} |
- "CLASS" [ ClassImplementation | ClassDeclaration ] ";" |
- ProcedureDeclaration ";" |
- ModuleDeclaration ";".
-
- ClassImplementation =
- className;
- [ AttributeDeclarations ]
- { MethodImplementation }
- [ "INIT" StatementSequence ]
- [ "DESTROY" StatementSequence ]
- "END" className .
-
- ClassDeclaration =
- className;
- [ "INHERIT" someClassName; ]
- [ AttributeDeclarations ]
- { MethodImplementation }
- [ "INIT" StatementSequence ]
- [ "DESTROY" StatementSequence ]
- "END" className .
-
- MethodImplementation = ProcedureDeclaration .
-
- An example of an Implementation Module incorporating CLASS definitions
- is:
-
- IMPLEMENTATION MODULE People;
- FROM Strings IMPORT CompareStr, Assign;
-
- CLASS Person; (* a class implementation *)
- PROCEDURE isMale() :BOOLEAN;
- BEGIN
- RETURN sex = male;
- END isMale;
-
-
-
- Classes 54
-
-
- INIT
- name := "";
- sex := unknown;
- END Person;
-
- CLASS Programmer; (* a class implementation *)
- PROCEDURE isSmart() :BOOLEAN;
- BEGIN
- RETURN CompareStr(favoriteLanguage,"Modula-2") = 0;
- END isSmart;
- INIT
- favoriteLanguage := "?";
- END Programmer;
-
- CLASS Vendor; (* a local class declaration *)
- INHERIT Programmer;
- BusinessAddress : ARRAY [0..40] OF CHAR;
- PROCEDURE GetAddress (VAR Address : ARRAY OF CHAR);
- BEGIN
- Assign(BusinessAddress, Address)
- END GetAddress;
- INIT
- BusinessAddress := "PO Box 867403, Plano, Texas"
- END Vendor;
- END People.
-
- Notes:
-
- 1. Local classes may be declared in program modules or
- implementation modules only at the outermost level, i.e. they
- may not be declared in local (nested) modules.
-
- 2. Further attributes may be added in a class implementation to
- those already defined in the class definition as it appears in
- the definition module.
-
- 3. Direct access to the attributes exported from the class
- definition is allowed, but should be avoided -- rather provide
- methods for accessing the attributes safely.
-
- 4. Inside a method, you have full access (with no need for
- qualification) to the fields of the object that you are dealing
- with.
-
- 5. When a method is called, the reference to the object on behalf
- of which the method will operate forms part of the message. If
- you need it, you may access this object's reference thru the
- predefined object handle SELF.
-
- 6. Thus in isSmart, above, we could have used SELF
-
-
-
-
-
-
- Classes 55
-
-
- RETURN CompareStr(SELF.favoriteLanguage,"Modula-2") = 0;
-
- but that is not necessary in this case. You would, typically,
- use SELF when you want to pass your object reference to a method
- of another class, as a parameter. We show an example of this in
- our Lists example.
-
-
-
-
-
-
- 12.5 Object instantiation
-
-
- We shall use the term "object handle" to describe the names given to
- instances of a class -- instances known as "objects". An object handle
- holds a reference (call it a pointer if you must) to an object
- instance.
-
- You declare an object handle just as you would declare a variable,
- using for its type the name of the class (of objects) that this handle
- will refer to. For example:
-
- VAR myBoss :Person;
-
- However, since in this implementation all objects are "dynamic",
- before you can use an object you must instantiate (create) it via a
- call to the standard procedure NEW, passing NEW the handle as a
- parameter. (This is somewhat analogous to using NEW to allocate
- storage for dynamically created variables accessed via other pointers
- in Modula-2). For example
-
- NEW( myBoss );
-
- NEW invokes the procedure ALLOCATEOBJECT, which allocates the
- necessary amount of storage to hold the object's data and then invokes
- the object's initialization code defined for the class. This
- initialization code is defined by the statement sequence following
- INIT in the class declaration or class implementation.
-
- Once you no longer need the object, you may get rid of it via the
- standard procedure DISPOSE. For example
-
- DISPOSE( myBoss );
-
- DISPOSE invokes the procedure DEALLOCATEOBJECT, which deallocates the
- necessary amount of storage to hold the object's data after invoking
- the object's destruction code defined for the class. This destruction
- code is defined by the statement sequence following DESTROY in the
- class declaration or class implementation.
-
- Implementations of the procedures ALLOCATEOBJECT and DEALLOCATEOBJECT
-
-
-
- Classes 56
-
-
- are found in the library module Objects (or you can write your own).
- Typically, an OOP module imports from Objects, of course.
-
- It may be desirable to have multiple object handles reference the same
- object. We can easily do this by assigning the value of an object
- handle to another object handle.
-
- objHandle2 := objHandle1;
-
- Please note that we are assigning object handles, not making a copy of
- the object itself. If we 'DISPOSE(objHandle1)', objHandle2 will hold
- an obsolete handle.
-
-
-
-
-
-
- 12.6 Object compatibility
-
-
- The possibility of assigning one object to another, or of passing
- objects as parameters to procedures or methods, brings us to the
- question of object type compatibility. Now the fun really begins!
-
- Two object handles are assignment compatible if they are of the same
- class type or if the class type of the source operand was derived from
- the class of the destination operand. For example, considering the
- declarations above,
-
- VAR myBoss :Person;
- me :Programmer (* inherits from Person *);
-
- me is assignment compatible with myBoss, but not the other way around:
-
- myBoss := me; (* right! *)
- me := myBoss; (* wrong *)
-
- If you think about it for a couple of minutes, you will agree that
- this makes sense. The class Person has methods that know how to deal
- with objects of that class. The class Programmer adds methods that
- know how to deal with the Programmer extensions to Person. If you
- applied a Programmer method (isSmart) to a non-Programmer Person, the
- method would fail because favoriteLanguage would not be a field of the
- Person structure. But a Person method (isMale) would have no trouble
- handling a Programmer, whose structure includes all the Person
- information. Let's not forget that the method Person.isMale is also a
- method of the class Programmer!
-
- The simple way to remember this is that an assignment is legal if the
- source can completely fill the destination (the fields that are left
- over are just "truncated", but not the reverse, as that would leave
- fields dangerously undefined).
-
-
-
- Classes 57
-
-
-
- Herein lies the power of object oriented programming. As you derive
- more specialized versions of a class, you inherit all the work done by
- whoever implemented its superclass.
-
- This implementation only supports "single inheritance" -- a subclass
- can only inherit directly from its one superclass. If we had multiple
- inheritance it would be even more fun, as we could inherit even more
- of other people's work at once!
-
-
-
-
- 12.6.0.1 Type compatibility of VAR object parameters
-
- The compatibility rules that govern assignment between pointers also
- apply to VAR object parameters.
-
-
-
-
- 12.6.0.2 Compatibility between Objects and other types
-
- Object handles are compatible with NIL and SYSTEM.ADDRESS.
-
-
-
-
-
-
- 12.7 The MEMBER function
-
-
- Clearly situations will arise where a procedure or method needs to
- know exactly what type its parameters are. This implementation makes
- available a standard function MEMBER to do just this.
-
- MEMBER( objectHandle, className )
-
- will return TRUE if the object is of the type className or className
- is an ancestor of the object's class.
-
- To use the function MEMBER, you must import MEMBEROBJECT from Objects
- (or write your own version of MEMBEROBJECT).
-
-
-
-
-
-
- 12.8 Complete example
-
-
-
-
-
- Classes 58
-
-
- Here is a simple example to illustrate the ideas of the last sections:
- using the classes declared in People.
-
- MODULE UsePeople;
- FROM InOut IMPORT
- WriteString, WriteLn;
- FROM People IMPORT
- Person, Programmer;
- FROM Objects IMPORT
- ALLOCATEOBJECT,DEALLOCATEOBJECT,MEMBEROBJECT;
- VAR
- someone :Person;
- smartProgrammer :Programmer;
- BEGIN
- NEW(smartProgrammer);
- smartProgrammer.favoriteLanguage := "Modula-2";
- someone := smartProgrammer;
- IF MEMBER(someone,Programmer) &
- smartProgrammer.isSmart()
- THEN
- WriteString( "he is a smart programmer!" );
- WriteLn;
- END;
- END UsePeople.
-
-
-
-
-
-
- 12.9 Virtual methods
-
-
- A programmer coming up with code like that above would be justifiably
- proud of the definition of a smart programmer... however, his boss,
- who might not know Modula-2, might not have liked it. As he put it,
- how smart a programmer is has more to do with the tools that he choses
- and how he uses them than simply what his favorite language is!
- Hmmm...
-
- To satisfy the boss, suppose we come up with this new class:
-
- DEFINITION MODULE MyKindOfProgrammers;
- FROM People IMPORT Programmer, LanguageName;
-
- CLASS Modula2Programmer;
- INHERIT Programmer;
- compilerVendor :ARRAY [0..2] OF CHAR;
- END Modula2Programmer;
-
- END MyKindOfProgrammers.
-
- This might be implemented as follows:
-
-
-
- Classes 59
-
-
-
- IMPLEMENTATION MODULE MyKindOfProgrammers;
- FROM Strings IMPORT CompareStr;
- CLASS Modula2Programmer;
- PROCEDURE isSmart() :BOOLEAN;
- BEGIN
- RETURN CompareStr(compilerVendor,"FST") = 0;
- END isSmart;
- INIT
- compilerVendor := "FST";
- END Modula2Programmer;
-
- END MyKindOfProgrammers.
-
- What about the boss?! Well, he can create his own programmer classes
- if he wants to!
-
- What have we done? Let's see how these classes could be used:
-
- MODULE x;
- FROM InOut IMPORT WriteString, WriteLn;
- FROM People IMPORT Programmer;
- FROM MyKindOfProgrammers IMPORT Modula2Programmer;
- FROM Objects IMPORT
- ALLOCATEOBJECT,DEALLOCATEOBJECT,MEMBEROBJECT;
-
- CLASS CProgrammer;
- INHERIT Programmer;
- END CProgrammer;
-
- VAR m2programmer :Modula2Programmer;
- cprogrammer :CProgrammer;
-
- BEGIN
- NEW( m2programmer );
- NEW( cprogrammer );
- IF m2programmer.isSmart() THEN
- WriteString( "this m2 programmer is smart" ); WriteLn;
- END;
- IF cprogrammer.isSmart() THEN
- WriteString( "this C programmer is smart" ); WriteLn;
- END;
- END x.
-
- This program would output "this m2 programmer is smart".
-
- In the implementation of Modula2Programmer we have effectively
- redefined the method isSmart, and so the message m2programmer.isSmart
- invokes this new method. But since CProgrammer did not redefine
- isSmart, the message cprogrammer.isSmart invokes the method
- implemented in Programmer. Makes sense, does it not?
-
- Now let us consider the following (similar) example:
-
-
-
- Classes 60
-
-
-
- MODULE y;
- FROM Objects IMPORT ALLOCATEOBJECT;
- FROM InOut IMPORT WriteString, WriteLn;
- FROM People IMPORT Programmer;
- FROM MyKindOfProgrammers IMPORT Modula2Programmer;
-
- CLASS CProgrammer;
- INHERIT Programmer;
- END CProgrammer;
-
- VAR m2programmer :Modula2Programmer;
- cprogrammer :CProgrammer;
-
- PROCEDURE ifIsSmart( p :Programmer; s :ARRAY OF CHAR );
- BEGIN
- IF p.isSmart() THEN
- WriteString( s ); WriteLn;
- END;
- END ifIsSmart;
-
- BEGIN
- NEW( m2programmer );
- NEW( cprogrammer );
- ifIsSmart( m2programmer, "1st m2 programmer is smart" );
- ifIsSmart( cprogrammer, "1st C programmer is smart" );
- m2programmer.favoriteLanguage := "C";
- cprogrammer.favoriteLanguage := "Modula-2";
- ifIsSmart( m2programmer, "2nd m2 programmer is smart" );
- ifIsSmart( cprogrammer, "2nd C programmer is smart" );
- END y.
-
- In this case we would get the following result:
-
- 1st m2 programmer is smart
- 2nd m2 programmer is smart
- 2nd C programmer is smart
-
- This may not be quite as obvious, although it certainly is what we
- would have wanted: Modula2Programmer's are smart, regardless of their
- favorite language, if they use FST Modula-2. By default, programmers
- are smart if their favorite language is Modula-2.
-
- Note further that
-
- MEMBER( cprogrammer, Modula2Programmer )
-
- would have returned FALSE, but
-
- MEMBER( cprogrammer, Person )
-
- would have returned TRUE.
-
-
-
-
- Classes 61
-
-
- How is it that the ifIsSmart method is invoking different procedures
- at different times, when the programmed call is, obviously, the same?
-
- Enter the world of dynamic binding. The procedure (method) invoked by
- p.isSmart in ifIsSmart is not determined until run time and it depends
- on the actual run time type of the object referenced by p.
-
-
-
-
-
-
- 12.10 For the technically minded
-
-
- Hmmm... Okay, time for a technical digression. Skip all this if you
- wish!
-
- When we declare a CLASS, the compiler generates a class template. The
- class template is a structure (the header of which is defined in
- Objects.DEF and shown bellow) that contains a reference to the parent
- class, the size of objects of this class and a pointer to each method
- in this class.
-
- ClassHeader = RECORD
- parent :Class;
- size :CARDINAL;
- filler :CARDINAL;
- InitProc :PROCEDURE( ADDRESS );
- DestroyProc :PROCEDURE( ADDRESS );
- ... other virtual methods ...
- END;
-
- When an object is created, the ALLOCATEOBJECT procedure allocates
- enough space to hold the data in the object's structure plus a pointer
- to the object's class. So, as you can see, regardless of the declared
- type of the object handle that refers to a particular object, we can,
- by looking at the object itself, determine what its real type is.
-
- As you might have guessed by now, we invoke a method by picking up its
- address from the class template referenced by the object itself.
-
- There is only one exception to this. As was stated earlier, methods
- declared in implementation modules are static. These methods cannot
- be redefined and, therefore, are not placed in the class template.
-
- In summary:
-
- A virtual method may be redefined and its invocation is
- dynamically resolved at run time.
-
- A static method cannot be redefined and its invocation is
- resolved at compile time.
-
-
-
- Classes 62
-
-
-
- All methods defined in a definition module are virtual. All
- methods first declared in a program or implementation module are
- static.
-
- It may also help to give a more insightful explanation of the methods
- INIT and DESTROY.
-
- We have seen that the methods defined in INIT and DESTROY are
- automatically invoked when an object is created or destroyed.
-
- When the compiler sees a NEW(objectHandle), it generates code that
- invokes the procedure ALLOCATEOBJECT, which must be known in the
- current environment -- you must either import this procedure from the
- standard module Objects or write your own.
-
- ALLOCATEOBJECT takes two parameters: a VAR object handle and a class
- identifier (pointer to the class template).
-
- First, ALLOCATEOBJECT calls Storage.ALLOCATE to allocate memory for
- the object and stores the address of the class template in the first
- double word of the object just allocated.
-
- Next, and starting with the base class in the hierarchy,
- ALLOCATEOBJECT invokes all the INIT methods that were defined along
- the way. In the previous example, the call NEW(m2programmer) caused
- person.INIT, Programmer.INIT and Modula2Programmer.INIT to be invoked,
- in that sequence.
-
- For DISPOSE(objectHandle), the compiler generates a call to
- DEALLOCATEOBJECT, also defined in Objects.
-
- DEALLOCATEOBJECT works in the reverse order of ALLOCATEOBJECT. It
- invokes all the DESTROY methods defined in the class hierarchy,
- starting with the class of the current object. It then invokes
- Storage.DEALLOCATE to free the object's memory.
-
-
-
-
-
-
- 12.11 On your own...
-
-
- This concludes our introduction to object oriented programming using
- FST Modula-2 v3.0.
-
- For another small example of the use of classes, please look at the
- modules Lists, MyLists and Uselists.
-
-
-
-
-
-
- Shareware 63
-
-
-
-
-
-
-
-
- Chapter 13
-
- Shareware
-
-
-
- This software package is distributed as Shareware.
-
- If you try this program and continue to use it, you are expected to
- register with us.
-
- This software can be freely distributed, as long as no money is
- charged for it, all the files are included, unmodified, and with their
- modification dates preserved.
-
- This software cannot be distributed as a part of another product.
-
- This software cannot be used in a commercial environment without the
- payment of the proper license fee.
-
- Our success will depend not only on the quality of this software but
- on the willingness of every individual user to "support" its
- developers. If you use this product, please send in the registration
- form in the back of this document, along with your registration fee.
- For a modest $50, we will send you the latest version of this software
- and all the library and runtime support source code. This source code
- is made available to registered users only.
-
- Whether or not you use this product, please give complete copies of
- this software to others.
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- License terms 64
-
-
-
-
-
-
-
-
- Chapter 14
-
- License terms
-
-
-
- Before you register this product and become a licensed user, you are
- granted a limited license to evaluate the product to determine whether
- or not it will fit your needs. Use of this system for any other
- purpose, before registration and without our written consent, is
- expressly forbidden.
-
- Registered users are given a non-exclusive license to use this
- software on any machine that they have access to, but not on more than
- one at a time (the "treat this software like a book" idea).
-
- Registered users may modify the source code provided to suit their
- needs, but this source code (in original or modified form) may not be
- distributed without the prior written consent of Fitted Software
- Tools.
-
- Registered users may include compiled portions of the library and
- runtime support code in the programs by them developed, and use or
- distribute these programs without payment of any additional license
- fees to Fitted Software Tools.
-
- We also provide an "educational site license". Schools may opt for
- this $250 license, instead of licensing enough copies of the compiler
- for all the machines that the compiler will be installed on.
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Support 65
-
-
-
-
-
-
-
-
- Chapter 15
-
- Support
-
-
-
- Support for this product is available by mail or through our BBS at
- 214/517-4629.
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- COMMENT FORM
-
-
- How did you first learn about this product?
-
- ---------------------------------------------------------
-
- Where did you get this software from?
-
- ( ) us ( ) a bulletin board
- ( ) a friend phone # ___ ___ ____
- ( ) a computer club ( ) a shareware software distributor
- ( ) other ________________________
-
- Systems you intend to use this software on
-
- ( ) PC (8088/8086) ( ) AT (80286) ( ) 80386 ( ) 80486
-
- Typical system's configuration
-
- ( ) hard disk
- ( ) 512k ( ) 640k
- ( ) extended memory
- ( ) expanded memory (EMS, EEMS)
- ( ) EGA adapter
- ( ) VGA adapter
-
- What programming languages do you use regularly?
-
- ---------------------------------------------------------
-
- What do you like the most about this system?
-
- _____________________________________________________________
- _____________________________________________________________
- _____________________________________________________________
- _____________________________________________________________
- _____________________________________________________________
-
- What do you NOT like about this system?
-
- _____________________________________________________________
- _____________________________________________________________
- _____________________________________________________________
- _____________________________________________________________
- _____________________________________________________________
-
- Other comments / suggestions:
-
-
-
-
-
-
-
-
-
-
-
- BUG REPORT
-
-
-
-
- Name_____________________________________________
-
- Company__________________________________________
-
- Address__________________________________________
-
- City, State, Zip_________________________________
-
- Country__________________________________________
-
- Telephone _____________
-
-
- Version of the software in use: ___________________________
-
- Machine in use (make and model): ___________________________
-
- Memory / Disks / Display type: ___________________________
-
- Operating system used: ___________________________
-
- Other system information that may be pertinent (PATH settings,
- CONFIG.SYS contents,...)
-
-
-
-
-
- Problem description:
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- REGISTRATION FORM
-
- Please mail this form to:
-
- Fitted Software Tools
- P.O.Box 867403
- Plano, TX 75086
-
- to register your copy/copies of the Modula-2 compiler, register/order
- additional copies, and/or order updates.
-
- The unauthorized distribution of the library and runtime support
- source code included in the distribution disks that you receive when
- you order a registered copy or update is specifically prohibited.
-
- If you are ordering multiple copies for your organization (or for you
- and your friends), we suggest that you order 1 of the $50 packages and
- pay $25 for each additional copy that you will make.
-
-
- Name_____________________________________________
-
- Company__________________________________________
-
- Address__________________________________________
-
- City, State, Zip_________________________________
-
- Country__________________________________________
-
-
- QTY
- ___ X Registration & latest version @ $50.00 (*) _________
-
- ___ X Additional Registration(s) @ $25.00 _________
-
- ___ X Educational site license @ $250.00 _________
-
- Total enclosed (**): _________
-
-
-
- Disk format preferred: 5-1/4" [ ] 360k [ ] 1.2MB
- 3.5" [ ] 720k [ ] 1.44MB
-
- Version of the software (the one displayed in the compiler screen)
- that you are currently using __________
-
- (*) We pay shipping worldwide. (**) Cheque or money order payable in
- the USA, please!
-
-
-
-
-
-
-
-
-
-
-
-
- Table of Contents
-
-
- Chapter 1 Introduction 3
-
- 1.1 A few words from the author 3
- 1.2 Hardware requirements 5
- 1.3 Software requirements 5
- 1.4 For users upgrading to release 3 5
-
- Chapter 2 Software installation 6
-
- 2.1 Theory 6
- 2.2 Recommended setup for a system with 2 floppy drives
- 8
- 2.3 Recommended setup for a hard disk system 8
-
- Chapter 3 A little tour through the system 10
-
- 3.1 The tour 10
-
- Chapter 4 The Compiler 13
-
- 4.1 Running the integrated compiler: MC 14
- 4.2 Running the freestanding compiler: M2COMP 16
- 4.3 The compilation process 16
-
- 4.3.0.1 The input file 16
- 4.3.0.2 The imported modules 16
- 4.3.0.3 The output file 17
- 4.3.0.4 A warning 17
-
- 4.4 Compiler directives 17
-
- 4.4.0.1 Benchmarks 18
-
- 4.5 Runtime errors 18
-
- 4.5.1 Trapping runtime errors in your program 19
-
- 4.6 Compiler size limits 19
- 4.7 The language supported 20
-
- 4.7.1 LONGINT and LONGCARD 20
- 4.7.2 LONGREAL 21
- 4.7.3 Additional or augmented standard procedures 21
-
- 4.7.3.1 NEW and DISPOSE -- pointer argument. 21
- 4.7.3.2 LONG and SHORT 22
- 4.7.3.3 FLOAT and TRUNC 22
-
-
-
-
-
- 4.8 Objects exported by the pseudo module SYSTEM 22
-
- 4.8.0.1 TYPE BYTE 22
- 4.8.0.2 TYPE WORD 23
- 4.8.0.3 TYPE ADDRESS 23
- 4.8.0.4 SEG and OFS 23
- 4.8.0.5 PROCEDURE ADR 24
- 4.8.0.6 PROCEDURE FLAT 24
- 4.8.0.7 PROCEDURE PTR 24
- 4.8.0.8 PROCEDURE SEGMENT 24
- 4.8.0.9 PROCEDURE OFFSET 24
- 4.8.0.10 PROCEDURE NEWPROCESS 24
- 4.8.0.11 PROCEDURE TRANSFER 24
- 4.8.0.12 PROCEDURE IOTRANSFER 25
- 4.8.0.13 ASSEMBLER 25
- 4.8.0.14 ASSEMBLER - 8087 support 26
-
- 4.9 The generated object code 27
-
- 4.9.1 Data type representation 27
- 4.9.2 The runtime memory map 28
- 4.9.3 Procedure calling conventions 29
-
- 4.9.3.1 Parameter passing (all except open array
- parameters) 29
- 4.9.3.2 Parameter passing (open array parameters)
- 29
- 4.9.3.3 Returning values from a function procedure
- 29
-
- 4.10 Module priorities 30
- 4.11 Memory models 31
-
- Chapter 5 Using OBJ files 32
-
- 5.1 GenLink 32
- 5.2 Foreign Modules 32
-
- 5.2.1 External names 33
- 5.2.2 Implementation 33
-
- 5.2.2.1 FOREIGN C modules 33
- 5.2.2.2 Parameter passing 34
-
- 5.2.3 In the real world... 35
-
- Chapter 6 The Text Editor 36
-
- Chapter 7 The Linker 38
-
- 7.1 Module keys 39
-
- Chapter 8 Other utilities 40
-
- 8.1 Editor configurator 40
-
-
-
-
- 8.2 Map file generator 40
- 8.3 Make and the Makefile generator 41
- 8.4 M2O file decoder 42
- 8.5 The execution profiler 42
-
- Chapter 9 The Library Modules 43
-
- 9.1 Release 3.0 libraries 43
-
- Chapter 10 The runtime support system 44
-
- Chapter 11 Modula-2 Syntax 45
-
- Chapter 12 Classes 47
-
- 12.1 Highlights of the implementation 47
- 12.2 Classes, attributes, methods, inheritance and
- polymorphism 48
- 12.3 Defining classes in definition modules 51
- 12.4 Implementing classes in implementation modules 53
- 12.5 Object instantiation 55
- 12.6 Object compatibility 56
-
- 12.6.0.1 Type compatibility of VAR object
- parameters 57
- 12.6.0.2 Compatibility between Objects and other
- types 57
-
- 12.7 The MEMBER function 57
- 12.8 Complete example 57
- 12.9 Virtual methods 58
- 12.10 For the technically minded 61
- 12.11 On your own... 62
-
- Chapter 13 Shareware 63
-
- Chapter 14 License terms 64
-
- Chapter 15 Support 65
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-